type Point struct {
    x int
    y int
}

type Player struct {
    name String
    score int
}

func capture_int_sum() int {
    var seed int = 5
    var adder func(int) int = func(delta int) int {
        seed + delta
    }
    seed = 50
    return adder(2)
}

func capture_string_snapshot() String {
    var prefix String = "Hello Nova"
    var snapshot func() String = func() String {
        prefix
    }
    prefix = "Bye Nova"
    return snapshot()
}

func capture_vector_snapshot() int {
    var numbers Vec<int> = Vec<int>{1, 2, 3}
    var snapshot func() int = func() int {
        numbers[0] + numbers[1] + numbers[2]
    }
    numbers[0] = 100
    numbers.push(400)
    return snapshot()
}

func capture_struct_point() int {
    var p Point = Point {
        x: 3,
        y: 4,
    }
    var area func() int = func() int {
        p.x * p.y
    }
    p.x = 10
    return area()
}

func capture_player_name() String {
    var player Player = Player {
        name: "Scout",
        score: 40,
    }
    var describe func() String = func() String {
        player.name
    }
    player.name = "Sniper"
    return describe()
}

func test_closure_capture_suite() {
    assert(capture_int_sum() == 7, "int capture should keep original seed")
    assert(
        capture_string_snapshot() == "Hello Nova",
        "string capture should snapshot prefix",
    )
    assert(
        capture_vector_snapshot() == 6,
        "vector capture should deep-copy contents",
    )
    assert(capture_struct_point() == 12, "struct capture should copy fields")
    assert(
        capture_player_name() == "Scout",
        "struct capture should preserve nested data",
    )

    println("closure capture tests passed")
}
